package com.da.auth.security.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.da.auth.entity.UserInfo;
import com.da.auth.entity.constant.DailyAuthConstant;
import com.da.auth.entity.dto.UserInfoDTO;
import com.da.auth.entity.vo.UserInfoVO;
import com.da.auth.mapper.UserInfoMapper;
import com.da.auth.redis.RedisCache;
import com.da.auth.security.jwt.BaseContext;
import com.da.auth.security.jwt.JwtClaimsConstant;
import com.da.auth.security.jwt.JwtUtils;
import com.da.auth.security.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author: hyacinth
 * @CreateTime: 2025-02-10
 * @Version: 1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    private final AuthenticationManager authenticationManager;
    private final RedisCache redisCache;

    private final JwtUtils jwtUtils;

    /**
     * 管理员登录
     * @param userInfoDTO 管理员登录表单
     * @return 员工登录VO
     */
    @Override
    public UserInfoVO login(UserInfoDTO userInfoDTO) {
        String username = userInfoDTO.getUsername();
        String password = userInfoDTO.getPassword();

        // 封装用户登录表单，创建未认证Authentication对象
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);
        // 进行校验
        Authentication authenticate = authenticationManager.authenticate(authentication);

        // 获取用户信息
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("用户名或密码错误");
        }
        UserInfo userInfo = (UserInfo) authenticate.getPrincipal();
        String userId = userInfo.getId();
        log.info("员工 {} 登录成功", userId);

        // 登录成功，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        // 使用fastjson的方法，把对象转换成json字符串
        String loginEmpString = JSON.toJSONString(userInfo);
        claims.put(JwtClaimsConstant.USERINFO_LOGIN, loginEmpString);
        String token;
        String cacheToken = (String) redisCache.getCacheObject(DailyAuthConstant.TOKEN_PREFIX + userId);
        if (StringUtils.isNotBlank(cacheToken)) {
            token = cacheToken;
        } else {
            token = jwtUtils.createJWT(claims);
            // 存储redis白名单
            String tokenKey = DailyAuthConstant.TOKEN_PREFIX + userId;
            redisCache.setCacheObject(tokenKey, DailyAuthConstant.TOKEN_PREFIX + token, DailyAuthConstant.TOKEN_EXPIRATION, TimeUnit.MINUTES);
        }
        BaseContext.setCurrentId(userId);
        //3、返回实体对象
        return UserInfoVO.builder()
                .id(userId)
                .token(token)
                .username(userInfo.getUsername())
                .build();
    }
}
